package com.jt.resource.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @author tang
 * @data 2021/9/27
 * @apiNode
 *
 * 在此配置类中配置令牌的生成个存储策略,配置令牌的验签方式(令牌合法性)
 */
@Configuration
public class TokenConfig {

    /**
     * JWT  令牌签名时使用的密钥(可以理解为盐值加密中的盐)
     *   1.生成的令牌需要这个密钥进行签名
     *   2.获取的令牌需要使用这个密钥进行验签(校验令牌合法性,是否被篡改过)
     */
    private static  String SIGNING_KEY = "auth";

    /**
     * 配置令牌的存储策略
     * 对于oauth2规范中提供了这样的几种策略:
     *      1.jdbcTokenStore(这里是要将token存储到关系型数据库)
     *      2.RadisTokenStore(这里是要将token存储到非关系型数据库）
     *      3.JWTTokenStore(这里是将产生的token信息存储到客户端,并且token中可以以自包含的形式存储一些用户信息)
     * @return
     */
    @Bean
    public TokenStore tokenStore(){
        //这里采用JWT方式生成和存储令牌信息
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 配置令牌的创建及验签方式
     * 基于此对象创建的令牌信息会封装到OAuth2AccessToken类型的对象中
     * 然后存储到TokenStore对象,外界需要时,会从tokenStore进行获取
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        //JWT令牌构成: header(签名算法,令牌类型),payLoad(数据部分),signing(签名)
        //这里的签名可以简单理解为加密,加密时会使用header中算法以及我们自己提供的密钥
        //这里加密的目的时为了防止令牌被篡改(这里的密钥要保管好,要存储到服务端)
        converter.setSigningKey(SIGNING_KEY);  //设置密钥
        return converter;
    }
}
